#include "include/flutter_yfree/flutter_yfree_plugin.h"
#include "YFree.h"

// This must be included before many other Windows headers.
#include <windows.h>

// For getPlatformVersion; remove unless needed for your plugin implementation.
#include <VersionHelpers.h>

#include <flutter/method_channel.h>
#include <flutter/plugin_registrar_windows.h>
#include <flutter/standard_method_codec.h>

#include <map>
#include <memory>
#include <sstream>

namespace
{
  class FlutterYfreePlugin : public flutter::Plugin
  {
  public:
    static void RegisterWithRegistrar(flutter::PluginRegistrarWindows *registrar);

    FlutterYfreePlugin();

    virtual ~FlutterYfreePlugin();

  private:
    // Called when a method is called on this plugin's channel from Dart.
    void HandleMethodCall(const flutter::MethodCall<flutter::EncodableValue> &method_call, std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result);
  };

  // static
  void FlutterYfreePlugin::RegisterWithRegistrar(flutter::PluginRegistrarWindows *registrar)
  {
    auto channel = std::make_unique<flutter::MethodChannel<flutter::EncodableValue>>(registrar->messenger(), "YFreePlugin", &flutter::StandardMethodCodec::GetInstance());

    auto plugin = std::make_unique<FlutterYfreePlugin>();

    channel->SetMethodCallHandler([plugin_pointer = plugin.get()](const auto &call, auto result)
                                  { plugin_pointer->HandleMethodCall(call, std::move(result)); });

    registrar->AddPlugin(std::move(plugin));
  }

  FlutterYfreePlugin::FlutterYfreePlugin() {}

  FlutterYfreePlugin::~FlutterYfreePlugin() {}

  void FlutterYfreePlugin::HandleMethodCall(const flutter::MethodCall<flutter::EncodableValue> &method_call, std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result)
  {
    if (method_call.method_name().compare("yAesEncrypt") == 0)
    {
        result->Success(flutter::EncodableValue(yAesEncrypt(yGetArgument(method_call, "content"), yGetArgument(method_call, "password"))));
    }
    else if (method_call.method_name().compare("yAesDecrypt") == 0)
    {
        result->Success(flutter::EncodableValue(yAesDecrypt(yGetArgument(method_call, "content"), yGetArgument(method_call, "password"))));
    }
    else
    {
      result->NotImplemented();
    }
  }

} // namespace

void FlutterYfreePluginRegisterWithRegistrar(FlutterDesktopPluginRegistrarRef registrar)
{
  FlutterYfreePlugin::RegisterWithRegistrar(flutter::PluginRegistrarManager::GetInstance()->GetRegistrar<flutter::PluginRegistrarWindows>(registrar));
}
